﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autofac;

namespace FlowBasis.Web.Autofac
{
    public class LifetimeScopeResolver : FlowBasis.Services.IServiceResolver, IDisposable
    {
        private ILifetimeScope lifetimeScope;

        public LifetimeScopeResolver(ILifetimeScope lifetimeScope)
        {
            this.lifetimeScope = lifetimeScope;
        }

        #region IServiceResolver Members

        public object Get(Type serviceType)
        {
            return this.lifetimeScope.Resolve(serviceType);
        }

        public object Get(Type serviceType, string serviceName)
        {
            return this.lifetimeScope.ResolveNamed(serviceName, serviceType);
        }

        public IEnumerable<object> GetAll(Type serviceType)
        {
            return (IEnumerable<object>)this.lifetimeScope.Resolve(typeof(IEnumerable<>).MakeGenericType(serviceType)); 
        }

        public object TryGet(Type serviceType)
        {
            object instance;
            if (this.lifetimeScope.TryResolve(serviceType, out instance))
            {
                return instance;
            }
            else
            {
                return null;
            }
        }

        public object TryGet(Type serviceType, string serviceName)
        {
            object instance;
            if (this.lifetimeScope.TryResolveNamed(serviceName, serviceType, out instance))
            {
                return instance;
            }
            else
            {
                return null;
            }
        }

        public T Get<T>() where T : class
        {
            return (T)this.Get(typeof(T));
        }

        public T Get<T>(string serviceName) where T : class
        {
            return (T)this.Get(typeof(T), serviceName);
        }

        public IEnumerable<T> GetAll<T>() where T : class
        {
            return this.GetAll(typeof(T)).Cast<T>();
        }

        public T TryGet<T>() where T : class
        {
            return (T)this.TryGet(typeof(T));
        }

        public T TryGet<T>(string serviceName) where T : class
        {
            return (T)this.TryGet(typeof(T), serviceName);
        }

        #endregion


        #region IDisposable Members

        public void Dispose()
        {
            if (this.lifetimeScope != null)
            {
                this.lifetimeScope.Dispose();
                this.lifetimeScope = null;
            }
        }

        #endregion
    }
}
